﻿package phpas3{
	
	public function date (format_str:String, timestamp:uint=0):String {
		var monthNames_array:Array = new Array("1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月");
		var dayNames_array:Array = new Array("日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日");


		var target_date:Date;
		if (timestamp == 0) {
			target_date = new Date();
			timestamp = target_date.getTime();
		} else {
			target_date = new Date (timestamp * 1000);
		}
		var heap_array:Array = format_str.split("");
		var resHeap_array:Array = new Array(heap_array.length);
		var escapeChar_str:String = "\\";
		//  you can change this to something different, but
		//  don't use a character that has a formatting meaning, 
		//  unless you want to disable it's functionality

		//  go through array and extract identifiers from its fields
		var temp:*;
		var firstDay:*;
		var thisDay:*;
		var len_num:uint = heap_array.length;
		for (var i = 0; i < len_num; i++) {
			switch (heap_array[i]) {
				case escapeChar_str :
					resHeap_array[i] = heap_array[i + 1];
					i++;
					break;

				case "a" ://  "am" or "pm"
					var a_num:uint = target_date.getHours();
					resHeap_array[i] = a_num < 12 ? "am":"pm";
					break;

				case "A" ://  "AM" or "PM"
					var A_num:uint = target_date.getHours();
					resHeap_array[i] = A_num < 12 ? "午前":"午後";
					break;

				case "d" ://  day of the month, 2 digits with leading zeros; i.e. "01" to "31"
					var d_str:String = String(target_date.getDate());
					resHeap_array[i] = d_str.length > 1 ? d_str:"0" + d_str;
					break;

				case "D" ://  day of the week, textual, 3 letters; i.e. "Fri"
					temp = dayNames_array[target_date.getDay()];
					resHeap_array[i] = temp.substring(0,3);

					break;

				case "F" ://  month, textual, long; i.e. "January"
					resHeap_array[i] = monthNames_array[target_date.getMonth()];
					break;

				case "g" ://  hour, 12-hour format without leading zeros; i.e. "1" to "12"
					temp = target_date.getHours();
					resHeap_array[i] = temp <= 12 ? temp:temp - 12;
					break;

				case "G" ://  hour, 24-hour format without leading zeros; i.e. "0" to "23"
					resHeap_array[i] = String(target_date.getHours());
					break;

				case "h" ://  hour, 12-hour format; i.e. "01" to "12"
					var h_num:uint = target_date.getHours();
					h_num = h_num <= 12 ? h_num:h_num - 12;
					resHeap_array[i] = String(h_num).length > 1 ? h_num:"0" + String(h_num);
					break;

				case "H" ://  hour, 24-hour format; i.e. "00" to "23"
					temp = String(target_date.getHours());
					resHeap_array[i] = temp.length > 1 ? temp:"0" + temp;
					break;

				case "i" ://  minutes; i.e. "00" to "59" 
					temp = String(target_date.getMinutes());
					resHeap_array[i] = temp.length > 1 ? temp:"0" + temp;
					break;

				case "I" ://  "1" if Daylight Savings Time, "0" otherwise. Works only on the northern hemisphere
					firstDay = new Date(target_date.getFullYear(),0,1);
					resHeap_array[i] = target_date.getTimezoneOffset() != firstDay.getTimezoneOffset() ? 1:0;
					break;

				case "j" ://  day of the month without leading zeros; i.e. "1" to "31" 
					resHeap_array[i] = target_date.getDate();
					break;

				case "l" ://  day of the week, textual, long; i.e. "Friday"
					resHeap_array[i] = dayNames_array[target_date.getDay()];
					break;

				case "L" ://  boolean for whether it is a leap year; i.e. "0" or "1" 
					resHeap_array[i] = target_date.getFullYear() % 4 ? false:true;
					break;

				case "m" ://  month; i.e. "01" to "12"
					temp = String(target_date.getMonth() + 1);
					resHeap_array[i] = temp.length > 1 ? temp:"0" + temp;
					break;

				case "M" ://  month, textual, 3 letters; i.e. "Jan"
					resHeap_array[i] = monthNames_array[target_date.getMonth()];
					break;

				case "n" ://  month without leading zeros; i.e. "1" to "12"
					resHeap_array[i] = target_date.getMonth() + 1;
					break;

				case "O" ://  Difference to Greenwich time in hours; i.e. "+0200"
					var minZone = target_date.getTimezoneOffset();
					var mins = minZone % 60;
					var hour = String(minZone - mins / 60 * -1);

					if (hour.charAt(0) != "-") {
						hour = "+" + hour;
					}

					hour = hour.length == 3 ? hour:hour.replace(/([+-])(\d)/,"$1" + 0 + "$2");
					resHeap_array[i] = hour + mins + "0";
					break;

				case "r" ://  RFC 822 formatted date; e.g. "Thu, 21 Dec 2000 16:01:07 +0200" 
					var dayName = dayNames_array[target_date.getDay()].substr(0,3);
					var monthName = monthNames_array[target_date.getMonth()].substr(0,3);
					resHeap_array[i] = dayName + ", " + target_date.getDate() + " " + monthName + date(" Y H:i:s O", timestamp);
					break;

				case "s" ://  seconds; i.e. "00" to "59"
					temp = String(target_date.getSeconds());
					resHeap_array[i] = temp.length > 1 ? temp:"0" + temp;
					break;

				case "S" ://  English ordinal suffix for the day of the month, 2 characters; i.e. "st", "nd", "rd" or "th"
					var S_num:uint = target_date.getDate();
					var suffixes_array:Array = new Array("st","nd","rd");
					var suffix_str:String = "";

					if (S_num >= 11 && S_num <= 13) {
						resHeap_array[i] = "th";
					} else {
						trace (String(S_num).substr(-1));
						resHeap_array[i] = suffix_str = suffixes_array[Number(String(S_num).substr(-1)) - 1] ? suffix_str:"th";
					}
					break;


				case "t" ://  number of days in the given month; i.e. "28" to "31" 
					resHeap_array[i] = target_date.getDay();
					break;

/* 
        *   T: Not implemented
        */

				case "U" ://  seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
					//  remember that this does not return milisecs!    
					resHeap_array[i] = Math.floor(target_date.getTime() / 1000);
					break;

				case "w" ://  day of the week, numeric, i.e. "0" (Sunday) to "6" (Saturday) 
					resHeap_array[i] = target_date.getDay();
					break;


				case "W" ://  ISO-8601 week number of year, weeks starting on Monday 
					var startOfYear = new Date(target_date.getFullYear(),0,1,0,0,0,0);
					firstDay = startOfYear.getDay() - 1;

					if (firstDay < 0) {
						firstDay = 6;
					}

					var firstMonday = Date.UTC(target_date.getFullYear(),0,8 - firstDay);
					thisDay = Date.UTC(target_date.getFullYear(),target_date.getMonth(),target_date.getDate());
					resHeap_array[i] = Math.floor(thisDay - firstMonday / 1000 * 60 * 60 * 24 * 7) + 2;
					break;

				case "y" ://  year, 2 digits; i.e. "99"
					resHeap_array[i] = String(target_date.getFullYear()).substring(2);
					break;

				case "Y" ://  year, 4 digits; i.e. "1999"
					resHeap_array[i] = target_date.getFullYear();
					break;

				case "z" ://  day of the year; i.e. "0" to "365" 
					firstDay = Date.UTC(target_date.getFullYear(),0,0);
					thisDay = Date.UTC(target_date.getFullYear(),target_date.getMonth(),target_date.getDate());
					resHeap_array[i] = Math.floor(thisDay - firstDay / 1000 * 60 * 60 * 24);
					break;

				case "Z" ://  timezone offset in seconds (i.e. "-43200" to "43200"). 
					resHeap_array[i] = target_date.getTimezoneOffset() * 60;
					break;

				default :
					resHeap_array[i] = heap_array[i];
			}
		}

		//  return joined array
		return resHeap_array.join("");
	}
}
